package me.twoday.library.mine.common.sns;

import java.io.IOException;
import java.net.MalformedURLException;

import me.twoday.library.mine.common.MessageUtil;
import me.twoday.library.mine.common.base.BaseApplication;
import me.twoday.library.mine.common.sns.Facebook.DialogListener;
import me.twoday.library.mine.common.sns.SessionEvents.AuthListener;
import me.twoday.library.mine.common.sns.SessionEvents.LogoutListener;
import me.twoday.library.mine.listener.AuthenticationListener;

import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;


/**
 * 페이스북 커넥터
 * 
 * @author 우연화
 * @since 2011.12.27
 */
public class FacebookConnector
{
	private static final String TAG = "FacebookConnector";
	private static FacebookConnector singletone;

	// 테스트용 앱 아이디: appTest
	private static final String APP_ID = "288825231211910";
	private static final String FACEBOOK_PERMISSION = "publish_stream";

	private Facebook facebook;

	private String[] permissions;

	private SessionListener mSessionListener = new SessionListener();

	private AuthenticationListener authListener;

	/**
	 * 커넥션 생성자
	 */
	private FacebookConnector()
	{
		this.facebook = new Facebook(APP_ID);

		SessionStore.restore(facebook, BaseApplication.getContext());
		SessionEvents.addAuthListener(mSessionListener);
		SessionEvents.addLogoutListener(mSessionListener);

		this.permissions = new String[]
		{FACEBOOK_PERMISSION};
	}

	/**
	 * 커넥터 인스턴스를 반환한다.
	 * 
	 * @return
	 */
	public static FacebookConnector getInstance()
	{
		if(singletone == null)
		{
			singletone = new FacebookConnector();
		}

		return singletone;
	}

	/**
	 * 페이스북 인증 여부를 확인한다.
	 * 
	 * @return
	 */
	public boolean isValid()
	{
		if(facebook.isSessionValid())
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	/**
	 * 인증 유효성을 체크하고 로그인 다이얼로그를 생성한다.
	 */
	public void login()
	{
		if(!facebook.isSessionValid())
		{
			facebook.authorize(BaseApplication.getTopActivity(), this.permissions, Facebook.FORCE_DIALOG_AUTH,
					new LoginDialogListener());
		}
	}

	/**
	 * 인증 유효성을 체크하지 않고 강제로 로그인 다이얼로그를 생성한다.
	 */
	public void loginForce()
	{
		facebook.authorize(BaseApplication.getTopActivity(), this.permissions, Facebook.FORCE_DIALOG_AUTH,
				new LoginDialogListener());
	}

	/**
	 * 페이스북 담벼락에 글을 작성한다.
	 * 
	 * @param msg
	 * @param url
	 */
	public void postMessageOnWall(String msg, String url)
	{
		if(facebook.isSessionValid())
		{
			AsyncTask<String, Boolean, Void> task = new AsyncTask<String, Boolean, Void>()
			{
				@Override
				protected Void doInBackground(String... params)
				{
					Boolean result = false;
					
					Bundle parameters = new Bundle();
					parameters.putString("message", params[0]);
					parameters.putString("link", params[1]);

					try
					{
						String response = facebook.request("me/feed", parameters, "POST");

						JSONObject object = new JSONObject(response);

						if(!object.isNull("id"))
						{
							result = true;
						}

						Log.i(TAG, response);
					}
					catch(IOException e)
					{
						result = false;
						Log.e(TAG, e.getMessage());
					}
					catch(JSONException e)
					{
						result = false;
						Log.e(TAG, e.getMessage());
					}

					publishProgress(result);

					return null;
				}

				@Override
				protected void onProgressUpdate(Boolean... values)
				{
					super.onProgressUpdate(values);

					Boolean result = values[0];

					if(result == null)
					{
						Toast.makeText(BaseApplication.getContext(), "페이스북 담벼락 글쓰기 요청을 실패하였습니다", Toast.LENGTH_SHORT).show();
					}
					else if(result)
					{
						Toast.makeText(BaseApplication.getContext(), "페이스북 담벼락 글을 작성하였습니다", Toast.LENGTH_SHORT).show();
					}
					else
					{
						Toast.makeText(BaseApplication.getContext(), "페이스북 담벼락 글쓰기 요청을 실패하였습니다", Toast.LENGTH_SHORT).show();
					}
				}
			};

			Toast.makeText(BaseApplication.getContext(), "페이스북 글쓰기 요청 중입니다", Toast.LENGTH_SHORT).show();
			task.execute(msg, url);
		}
		else
		{
			login();
		}
	}

	/**
	 * 페이스북 담벼락에 글을 작성한다.
	 * 
	 * @param msg
	 * 
	 */
	public void postMessageOnWall(String msg)
	{
		if(facebook.isSessionValid())
		{
			AsyncTask<String, Boolean, Void> task = new AsyncTask<String, Boolean, Void>()
			{
				@Override
				protected Void doInBackground(String... params)
				{
					Boolean result = false;

					Bundle parameters = new Bundle();
					parameters.putString("message", params[0]);

					try
					{
						String response = facebook.request("me/feed", parameters, "POST");

						JSONObject object = new JSONObject(response);

						if(!object.isNull("id"))
						{
							result = true;
						}

						Log.i(TAG, response);
					}
					catch(IOException e)
					{
						result = false;
						Log.e(TAG, e.getMessage());
					}
					catch(JSONException e)
					{
						result = false;
						Log.e(TAG, e.getMessage());
					}

					publishProgress(result);

					return null;
				}

				@Override
				protected void onProgressUpdate(Boolean... values)
				{
					super.onProgressUpdate(values);

					Boolean result = values[0];

					if(result == null)
					{
						Toast.makeText(BaseApplication.getContext(), "페이스북 담벼락 글쓰기 요청을 실패하였습니다", Toast.LENGTH_SHORT).show();
					}
					else if(result)
					{
						Toast.makeText(BaseApplication.getContext(), "페이스북 담벼락 글을 작성하였습니다", Toast.LENGTH_SHORT).show();
					}
					else
					{
						Toast.makeText(BaseApplication.getContext(), "페이스북 담벼락 글쓰기 요청을 실패하였습니다", Toast.LENGTH_SHORT).show();
					}
				}
			};

			task.execute(msg);
		}
		else
		{
			login();
		}
	}

	/**
	 * 페이스북 친구 리스트를 가져온다.
	 */
	public void getFriendsList()
	{
		if(facebook.isSessionValid())
		{
			AsyncTask<Void, Object, Void> task = new AsyncTask<Void, Object, Void>()
			{

				@Override
				protected Void doInBackground(Void... params)
				{
					Boolean result = false;
					String response = null;
					
					
					try
					{
						result = true;
						response = facebook.request("me/friends");
					}
					catch(MalformedURLException e)
					{
						result = false;
						Log.e(TAG, e.getMessage());
					}
					catch(IOException e)
					{
						result = false;
						Log.e(TAG, e.getMessage());
					}	
					
					publishProgress(result, response);

					return null;
				}
				
				@Override
				protected void onProgressUpdate(Object... values)
				{
					super.onProgressUpdate(values);
					
					Boolean result = (Boolean) values[0];
					
					if(result == null)
					{
						Toast.makeText(BaseApplication.getContext(), "페이스북 친구 목록 요청을 실패하였습니다", Toast.LENGTH_SHORT).show();
					}
					else if(result)
					{
						Toast.makeText(BaseApplication.getContext(), "페이스북 친구 목록 요청을 성공하였습니다", Toast.LENGTH_SHORT).show();
						String response = (String) values[1];
						MessageUtil.alert(BaseApplication.getTopActivity(), response);
					}
					else
					{
						Toast.makeText(BaseApplication.getContext(), "페이스북 친구 목록 요청을 실패하였습니다", Toast.LENGTH_SHORT).show();
					}
				}
			};
			
			task.execute();
		}
		else
		{
			login();
		}
	}
	
	/**
	 * 페이스북 인증(로그인) 다이얼로그를 생성한다.
	 * 
	 * @author 우연화
	 * @since 2011.12.27
	 */
	private final class LoginDialogListener implements DialogListener
	{
		public void onComplete(Bundle values)
		{
			SessionEvents.onLoginSuccess();
		}

		public void onFacebookError(FacebookError error)
		{
			SessionEvents.onLoginError(error.getMessage());
		}

		public void onError(DialogError error)
		{
			SessionEvents.onLoginError(error.getMessage());
		}

		public void onCancel()
		{
			SessionEvents.onLoginError("Action Canceled");
		}
	}

	/**
	 * 세션 리스너 클래스
	 * 
	 * @author 우연화
	 * @since 2011.12.27
	 */
	private class SessionListener implements AuthListener, LogoutListener
	{
		public void onAuthSucceed()
		{
			// 인증 성공시 세션을 저장한다.
			SessionStore.save(facebook, BaseApplication.getContext());
			Toast.makeText(BaseApplication.getContext(), "페이스북 인증되었습니다.", Toast.LENGTH_SHORT).show();
			
			if(authListener != null)
			{
				authListener.onLoginSuccessWithFacebook();
			}
		}

		public void onAuthFail(String error)
		{
			Toast.makeText(BaseApplication.getContext(), "페이스북 인증이 실패하였습니다.", Toast.LENGTH_SHORT).show();
		}

		public void onLogoutBegin()
		{
		}

		public void onLogoutFinish()
		{
			// 로그아웃을 하면 세션을 클리어 한다.
			SessionStore.clear(BaseApplication.getContext());
			
			Toast.makeText(BaseApplication.getContext(), "페이스북 연결을 끊었습니다.", Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * 페이스북 인스턴스를 반환한다.
	 * 
	 * @return
	 */
	public Facebook getFacebook()
	{
		return facebook;
	}

	/**
	 * 페이스북 인스턴스를 설정한다.
	 * 
	 * @param facebook
	 */
	public void setFacebook(Facebook facebook)
	{
		this.facebook = facebook;
	}

	public AuthenticationListener getAuthListener()
	{
		return authListener;
	}

	public void setAuthListener(AuthenticationListener authListener)
	{
		this.authListener = authListener;
	}

}
